package blackjack;

import java.util.LinkedList;
import javax.swing.JOptionPane;

public class Game {


	// why do these need to be static?  wtf is static anyways?
	static String dShowingStr;
	static String dCountStr;
	static Hand pHand;
	static Hand dHand;
	static boolean dFlip = false;

	LinkedList<Card> pCards = pHand.cards;
	LinkedList<Card> dCards = dHand.cards; 

	// working now - replaced all the calls to new Status with a single method
	static Status stat() {
		return new Status(dHand, pHand, dFlip);
	}


	// this is the game
	public static void main(String[] args) {

		//new Popup();
		//new Popup("Hello");
		//new Popup("Hello", "This is a title!");


		int bankroll = 100;
		int bet = 10;
		int dealerCount;

		// game over when bankroll is gone
		while (bankroll > 0) {

			try { // NullPointerException if player clicks cancel instead of ok

				// new hand - get player bet
				boolean betDone = false;
				String answerStr = (String) javax.swing.JOptionPane.showInputDialog(null, "Bankroll: "+bankroll+"\n\nWhat is your bet?", "Bet", JOptionPane.PLAIN_MESSAGE, null, null, bet);

				// data validation loop - set betDone true when bet is int within bankroll
				// add bet = 0 failure

				while (betDone == false) {
					// if answer is int...
					if (answerStr.matches("((-|\\+)?[0-9]+)+")) {
						// check against bankroll... 
						bet = Integer.parseInt(answerStr); 
						if (bet > bankroll) { // is bet bigger than bankroll?
							// bet is too big message 
							answerStr = (String) javax.swing.JOptionPane.showInputDialog(null, "Try again: ", "Bet", JOptionPane.PLAIN_MESSAGE, null, null, "You don't have that much $");}
						// bet is ok (int and less or equal to bankroll) 
						else {betDone = true;}} 
					// bet is not integer message
					else {answerStr = (String) javax.swing.JOptionPane.showInputDialog(null, "Try again: ", "Bet", JOptionPane.PLAIN_MESSAGE, null, null, "You didn't type a number");};
				} // end of bet while loop
			} // end of try block 

			// player clicked cancel - end game
			catch (NullPointerException ex) {
				new Popup("You quit!", "Quitters never win!");
				System.exit(0); }


			// deal - set up list of cards for dealer's hand and list of cards for player's hand
			boolean pBust = false;
			boolean dBust = false;
			boolean pStand = false;
			dFlip = false;
			
			dHand = new Hand();
			pHand = new Hand();
			
			
			LinkedList<Card> dCards = dHand.cards;
			LinkedList<Card> pCards = pHand.cards;
			 

			// show first status
			stat();

			// calculate player total count (ace is 11) for hit message title
			int pCount = pHand.count();
			//for (Card c : pCards) {
			//pCount = pCount+c.cardVal;
			//}

			// player hit/stand/bust loop
			while (!pStand && !pBust) {

				// prompt for hit
				int hit = JOptionPane.showConfirmDialog(null, "Would you like another card?", "Your count is: " + pCount, JOptionPane.YES_NO_OPTION);
				if (hit == 1) {pStand = true;} // player stands

				if (hit == 0) { // player hits...		
					pCards.add(new Card());
					JOptionPane.showMessageDialog(null, "You get a new card:\n"+pCards.getLast().fullName, "Hit", JOptionPane.INFORMATION_MESSAGE);
					// increment count
					pCount = pCount + pCards.getLast().cardVal;
					// updated status
					stat();

					// check bust and popup if true
					if (pCount > 21) {
						pBust = true;
						JOptionPane.showMessageDialog(null, "You busted!", "Busted", JOptionPane.INFORMATION_MESSAGE);
					}

				} // end of hit loop, ask again if player hasn't busted

			} // either player stands or busts to end this loop

			// populate dealer hand string and count
			dFlip = true;
			dealerCount = 0;
			dShowingStr = "Dealer is showing:";
			for (Card c : dCards) {
				dShowingStr = dShowingStr + "\n" + c.fullName;
				dealerCount = dealerCount+c.cardVal;
			}
			dCountStr = ""+dealerCount;

			// show new status after dealer "flips"
			stat();


			if (!pBust) { // skip dealer hit and bust check if player busted

				while (dealerCount < 17) {
					// dealer hits under 17
					dCards.add(new Card());
					JOptionPane.showMessageDialog(null, "Dealer takes a card:\n"+dCards.getLast().fullName, "Hit", JOptionPane.INFORMATION_MESSAGE);
					// increment count and showing string
					dealerCount = dealerCount + dCards.getLast().cardVal;
					dCountStr = ""+dealerCount;
					dShowingStr = dShowingStr+"\n"+dCards.getLast().fullName;
					// update status
					stat();
				}

			} // dealer is >= 17


			// check dealer bust
			if (dealerCount > 21) {
				dBust = true;
				JOptionPane.showMessageDialog(null, "Dealer busted!", "Busted", JOptionPane.INFORMATION_MESSAGE);
			}

			// determine payout
			if (dBust) {bankroll = bankroll+bet; JOptionPane.showMessageDialog(null, "You win! (Bust)", "Win", JOptionPane.INFORMATION_MESSAGE);};
			if (pBust) {bankroll = bankroll-bet; JOptionPane.showMessageDialog(null, "You lose! (Bust)", "Lose", JOptionPane.INFORMATION_MESSAGE);};
			if (dealerCount == pCount) {JOptionPane.showMessageDialog(null, "You tie!", "Push", JOptionPane.INFORMATION_MESSAGE);};
			if (dealerCount < pCount && !pBust && !dBust) {bankroll = bankroll+bet; JOptionPane.showMessageDialog(null, "You win! (Count)", "Win", JOptionPane.INFORMATION_MESSAGE);};
			if (dealerCount > pCount && !pBust && !dBust) {bankroll = bankroll-bet; JOptionPane.showMessageDialog(null, "You lose! (Count)", "Lose", JOptionPane.INFORMATION_MESSAGE);};

		} // bankroll = 0


	} //  main definition			
} // class definition


// This is to enable keyboard navigation in JOptionPanes...  not working yet
/*
UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE);
configureOptionPane();
}

private static void configureOptionPane() {
if(UIManager.getLookAndFeelDefaults().get("OptionPane.actionMap") == null)
{
	UIManager.put("OptionPane.windowBindings", new 
			Object[] {
			"ESCAPE", "close",
			"LEFT", "left",
			"KP_LEFT", "left",
			"RIGHT", "right",
			"KP_RIGHT", "right"
	});
	ActionMap map = new ActionMapUIResource();
	map.put("close", new OptionPaneCloseAction());
	map.put("left", new OptionPaneArrowAction(false));
	map.put("right", new OptionPaneArrowAction(true));
	UIManager.getLookAndFeelDefaults().put
	("OptionPane.actionMap", map);
}
}
private static class OptionPaneCloseAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
	JOptionPane optionPane = (JOptionPane) e.getSource();
	optionPane.setValue(JOptionPane.CLOSED_OPTION);
}
}
private static class OptionPaneArrowAction extends AbstractAction {

private static final long serialVersionUID = 1L;
private boolean myMoveRight;
OptionPaneArrowAction(boolean moveRight) {
	myMoveRight = moveRight;
}
public void actionPerformed(ActionEvent e) {
	JOptionPane optionPane = (JOptionPane) e.getSource();
	EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();

	eq.postEvent(new KeyEvent(
			optionPane,
			KeyEvent.KEY_PRESSED,
			e.getWhen(),
			(myMoveRight) ? 0 : InputEvent.SHIFT_DOWN_MASK,
					KeyEvent.VK_TAB,
					KeyEvent.CHAR_UNDEFINED,
					KeyEvent.KEY_LOCATION_UNKNOWN
			));
}
}*/
